package cn.jhz.learn.blog.service.security.resource.blog.impl;

import cn.jhz.learn.blog.common.exception.ParamException;
import cn.jhz.learn.blog.component.GLOBAL;
import cn.jhz.learn.blog.component.ValidationHolder;
import cn.jhz.learn.blog.dao.blogger.BlogBloggerMapper;
import cn.jhz.learn.blog.dao.blogger.BlogBloggerSubscribeMapper;
import cn.jhz.learn.blog.po.blogger.BlogBlogger;
import cn.jhz.learn.blog.po.blogger.BlogBloggerSubscribe;
import cn.jhz.learn.blog.service.security.resource.blog.BlogValidationService;

import org.springframework.stereotype.Service;

@Service("blogValidationService")
public class BlogValidationServiceImpl implements BlogValidationService {

    private final BlogBloggerMapper mapper;
    private final BlogBloggerSubscribeMapper subscribeMapper;


    public BlogValidationServiceImpl(BlogBloggerMapper mapper, BlogBloggerSubscribeMapper subscribeMapper) {
        this.mapper = mapper;
        this.subscribeMapper = subscribeMapper;
    }

    @Override
    public BlogBlogger valid(String blogName) {
        BlogBlogger blogger =
                (BlogBlogger) ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_BLOGGER.BLOG_NAME + blogName);
        if(blogger == null) {
            blogger = mapper.selectByBlogName(blogName);
            permissionValid(blogger);
            ValidationHolder.putParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_BLOGGER.BLOG_NAME  + blogName, blogger);
        }
        return blogger;
    }

    @Override
    public BlogBlogger valid(Integer id) {
        BlogBlogger blogger =
                (BlogBlogger) ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_BLOGGER.ID + id);
        if(blogger == null) {
            blogger = mapper.selectByPrimaryKey(id);
            permissionValid(blogger);
            ValidationHolder.putParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_BLOGGER.ID  + id, blogger);
        }
        return blogger;
    }

    @Override
    public BlogBlogger valid(Integer uid, String blogName) {
        BlogBlogger user = uidValid(uid);
        BlogBlogger blogger =
                (BlogBlogger) ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_BLOGGER.BLOG_NAME + blogName);

        if(blogger == null) {
            blogger = mapper.selectByBlogName(blogName);

            permissionUidValid(user, blogger);
            ValidationHolder.putParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_BLOGGER.BLOG_NAME + blogName, blogger);
        }
        return blogger;
    }

    @Override
    public BlogBlogger valid(Integer uid, Integer id) {
        BlogBlogger user = uidValid(uid);
        BlogBlogger blogger =
                ((BlogBlogger)ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_BLOGGER.ID + id));

        if(blogger == null) {
            blogger = mapper.selectByPrimaryKey(id);
            permissionUidValid(user, blogger);

            ValidationHolder.putParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_BLOGGER.ID + id, blogger);
        }
        return blogger;
    }

    @Override
    public BlogBlogger uidValid(Integer uid) {
        BlogBlogger user = ValidationHolder.getCurrentUser();
        if(user == null) {
            user = mapper.selectByUid(uid);
            if(user == null)
                throw new ParamException("博客不存在!");
            else if (user.getStatus().equals(GLOBAL.RESOURCE.STATUS.VALID))
                ValidationHolder.setUserHolder(user);
            else
                throw new ParamException("账号异常, 请联系管理员!");
            ValidationHolder.setUserHolder(user);
        }
        ValidationHolder.putParam(
                GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.OWN_LEVEL + user.getId(),
                GLOBAL.RESOURCE.OWN_LEVEL.OWN
        );
        return user;
    }

    private void permissionValid(BlogBlogger blogger) {
        if (blogger == null)
            throw new ParamException("博客不存在!");
        else if (blogger.getStatus().equals(GLOBAL.RESOURCE.STATUS.VALID))
            switch(blogger.getVisibility()){
                case 0:
                    throw new ParamException("该博客未公开!");
                case 1:
                    ValidationHolder.putParam(GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.OWN_LEVEL + blogger.getId(),
                            GLOBAL.RESOURCE.OWN_LEVEL.PUBLIC);
                    break;
                case 2:
                    throw new ParamException("未订阅该博客!");
                default:
                    throw new ParamException("数据库记录异常!:" + BlogBlogger.class.getName() + ":id:" + blogger.getId());
            }
        else
            throw new ParamException("该博客已被暂停使用!");
    }

    private void permissionUidValid(BlogBlogger user, BlogBlogger blogger) {
        if (blogger == null)
            throw new ParamException("博客不存在!");
        else if (blogger.getId().equals(user.getId()))
            ValidationHolder.putParam(
                    GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.OWN_LEVEL + blogger.getId(),
                    GLOBAL.RESOURCE.OWN_LEVEL.OWN
            );
        else if (blogger.getStatus().equals(GLOBAL.RESOURCE.STATUS.VALID))
            switch (blogger.getVisibility()) {
                case 0:
                    throw new ParamException("该博客未公开!");
                case 1:
                    ValidationHolder.putParam(
                            GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.OWN_LEVEL + blogger.getId(),
                            GLOBAL.RESOURCE.OWN_LEVEL.PUBLIC
                    );
                    break;
                case 2:
                    BlogBloggerSubscribe subscribe =
                            (BlogBloggerSubscribe) ValidationHolder.getParam(
                            GLOBAL.VALIDATION_KEY.CLASS_BLOG_BLOGGER_SUBSCRIBE.ID + blogger.getId() + "&" + user.getId());
                    if (subscribe == null) {
                        subscribe = subscribeMapper.selectByBlogIdAndSubscriberId(blogger.getId(), user.getId());
                        if (subscribe == null)
                            throw new ParamException("未订阅当前博客!");
                        else if(subscribe.getStatus().equals(GLOBAL.RESOURCE.STATUS.VALID)) {
                            ValidationHolder.putParam(
                                    GLOBAL.VALIDATION_KEY.CLASS_BLOG_BLOGGER_SUBSCRIBE.ID + blogger.getId() + "&" + user.getId(), subscribe);
                            ValidationHolder.putParam(
                                    GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.OWN_LEVEL  + blogger.getId(),
                                    GLOBAL.RESOURCE.OWN_LEVEL.SUBSCRIBE
                            );
                        }else
                            throw new ParamException("未订阅当前博客!");
                    }
                    break;
                default:
                    throw new RuntimeException("数据库记录异常!:" + BlogBlogger.class + ":id:" + blogger.getId());
            }
        else
            throw new ParamException("该博客已被暂停使用!");
    }
}
